﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Library;

namespace Directory
{
  /// <summary>
  /// 組織単位リスト画面のフォームです。
  /// </summary>
  public partial class OUList : Form
  {
    #region プライベートフィールド
    private readonly IList<OrganizationalUnit> ouCol;   //OUのコレクション
    #endregion

    #region パブリックコンストラクター
    /// <summary>
    /// OUList クラスの新しいインスタンスを初期化します。
    /// </summary>
    public OUList()
    {
      InitializeComponent();

      var ous = DirectoryAccess.GetOrganizationalUnits();   //OUを取得
      ouCol = ous.OrderBy(ou => ou.DisplayPath).ThenBy(ou => ou.Name).ToList();
      this.OUBindingSource.DataSource = ouCol;
      this.CountLabel.Text = String.Format("{0} 個のオブジェクト", this.OUBindingSource.Count);
      this.AddChildNode(null);  //子ノードを追加
      this.OUTreeView.ExpandAll();
    }
    #endregion

    #region イベントハンドラ
    private void OUTreeView_AfterSelect(object sender, TreeViewEventArgs e)
    {
      var selectedOU = ouCol.Single(ou => ou.Entry.Path.Equals(e.Node.Tag.ToString()));
      this.OUBindingSource.Position = this.OUBindingSource.IndexOf(selectedOU);
      this.ShowStoredData(selectedOU);  //格納されているデータを表示
    }
    #endregion

    #region プライベートメソッド
    /// <summary>
    /// 子ノードを追加します。
    /// </summary>
    /// <param name="node">子ノードを追加するノード。</param>
    private void AddChildNode(TreeNode node)
    {
      var path = (node == null) ? String.Empty : node.FullPath;
      var childOUs = ouCol.Where(ou => ou.DisplayPath.Equals(path)).ToList();   //直下のOU

      foreach (var ou in childOUs)
      {
        var childNode = CreateNode(ou);   //ノードを作成
        if (node == null)
        {
          this.OUTreeView.Nodes.Add(childNode);
        }
        else
        {
          node.Nodes.Add(childNode);
        }
        this.AddChildNode(childNode);   //子ノードを追加
      }
    }

    /// <summary>
    /// 指定した OU のノードを作成します。
    /// </summary>
    /// <param name="ou">OU。</param>
    /// <returns>作成したノード。</returns>
    private TreeNode CreateNode(OrganizationalUnit ou)
    {
      var path = (ou.DisplayPath.Length == 0) ? String.Empty : ou.DisplayPath + "/";
      return new TreeNode(ou.Name) { Name = path + ou.Name, Tag = ou.Entry.Path };
    }

    /// <summary>
    /// 格納されているデータを表示します。
    /// </summary>
    /// <param name="ou">OU。</param>
    private void ShowStoredData(OrganizationalUnit ou)
    {
      string[] subItem = new string[3];   //名前と所属パスの配列
      this.DataListView.Items.Clear();
      foreach (var domainObject in ou.StoredDomainObjects)  //直下のオブジェクト数分
      {
        var objectType = (CategoryType)Enum.Parse(typeof(CategoryType), domainObject.Entry.SchemaClassName, true);
        subItem[0] = domainObject.Name;   //名前をセット
        subItem[1] = DirectoryAccess.CategoryNames[(int)objectType];    //種類をセット
        subItem[2] = domainObject.Description;  //説明をセット
        this.DataListView.Items.Add(new ListViewItem(subItem, (int)objectType));
      }
      this.DataCountLabel.Text = String.Format("{0} 個のオブジェクト", ou.StoredDomainObjects.Count);
    }
    #endregion
  }
}
